#include <iostream>
#include <vector>
#include <cstring>

#define maxn 20002
#define oo 1000000000

using namespace std;

struct edge {
	int b, w;
};
vector< vector<edge> > e;

int dist[maxn], heap[maxn], pos[maxn];
int ntest, n, m, s, t, l;

void input()
{
	cin >> n >> m >> s >> t;
	s++;
	t++;

	e.clear();
	for (int u = 0; u <= n; u++)
	{
		vector<edge> t;
		e.push_back(t);
	}

	for (int i = 0; i < m; i++)
	{
		int u, v, w;
		cin >> u >> v >> w;

		edge t;

		t.b = v+1;
		t.w = w;
		e[u+1].push_back(t);

		t.b = u+1;
		t.w = w;
		e[v+1].push_back(t);
	}
}

void upheap(int u)
{
	int node = heap[u];
	while (u > 1)
	{
		if (dist[node] >= dist[heap[u/2]]) break;
		pos[heap[u/2]] = u;
		heap[u] = heap[u/2];
		u /= 2;
	}
	heap[u] = node;
	pos[node] = u;
}

void downheap(int u)
{
	int node = heap[u];
	u *= 2;
	while (u <= l)
	{
		if (u < l && dist[heap[u]] > dist[heap[u+1]]) u++;
		if (dist[heap[u]] >= dist[node]) break;
		heap[u/2] = heap[u];
		pos[heap[u]] = u/2;
		u *= 2;
	}
	heap[u/2] = node;
	pos[node] = u/2;
}

void init()
{
	for (int u = 1; u <= n; u++)
	{
		dist[u] = oo;
		heap[u] = u;
		pos[u] = u;
	}
	dist[s] = 0;
	upheap(pos[s]);
}

void process()
{
	init();
	l = n;
	while (l > 0)
	{
		int u = heap[1];

		heap[1] = heap[l];
		pos[heap[1]] = 1;
		l--;

		downheap(1);

		if (dist[u] == oo) break;

		for (int i = 0; i < e[u].size(); i++)
		{
			int v = e[u][i].b;
			if (dist[v] > dist[u] + e[u][i].w)
			{
				dist[v] = dist[u] + e[u][i].w;
				upheap(pos[v]);
			}
		}
	}
}

void output()
{
	if (dist[t] == oo) cout << "unreachable" << endl;
	else cout << dist[t] << endl;
}

int main()
{
	//freopen("10986.in", "r", stdin);

	cin >> ntest;
	for (int run = 1; run <= ntest; run++)
	{
		cout << "Case #" << run << ": ";
		input();
		process();
		output();
	}
	return 0;
}
